package com.botann.projects.utils;

import com.botann.projects.annotations.Expand;
import com.botann.projects.annotations.Expand;
import com.botann.projects.annotations.Pass;
import org.apache.log4j.Logger;

import java.lang.reflect.Field;

/**
 * Charging
 * ModelUtils
 * Created by 刘山国 on 2017/11/21.
 * Copyright (c) 2017 刘山国. All rights reserved
 */
public final class ModelUtils {

    private static Logger logger = Logger.getLogger(ModelUtils.class);

    /**
     * 使用扩展注解Expand之后,基本不可能使用继承父类,所以containSuper基本没有意义,但是处理方式是默认包含父类属性的
     */

    /**
     * Get Class Fields, Default contains super's fields TRUE contains expand false 包含父类属性,不包含扩展属性
     * @param clazz Class
     * @param alias 前缀
     * @return StringBuilder
     */
    public static StringBuilder getFields(Class clazz,String alias){
        return getFields(clazz,alias,true,false);
    }

    /**
     * Get Class Fields, Default contains super's fields TRUE contains expand true 包含父类属性,包含扩展属性
     * @param clazz Class
     * @param alias 前缀
     * @return StringBuilder
     */
    public static StringBuilder getFieldsE(Class clazz,String... alias) {
        return getFields(clazz,alias,true,true);
    }

    /**
     * Get Class Fields
     * @param clazz Class
     * @param tableTag 表前缀, 第0个是搜索表的alias ,后面的是排除的
     * @param containSuper 是否包含所有父类属性
     * @param containExpand 是否包含@Expand 注解的扩展属性
     * @return StringBuilder
     */
    public static StringBuilder getFields(Class clazz,String tableTag, Boolean containSuper, Boolean containExpand) {
        String tableTags[] = {tableTag};
        return getFields(clazz,tableTags,containSuper,containExpand);
    }
    public static StringBuilder getFields(Class clazz,String[] tableTags, Boolean containSuper, Boolean containExpand){
        StringBuilder stringBuilder = new StringBuilder("");
        String mTableTag;
        String fieldName;
        while (clazz != null) {
            /*getFields()：获得某个类的所有的公共（public）的字段，包括父类中的字段。
              getDeclaredFields()：获得某个类的所有声明的字段，即包括public、private和proteced，但是不包括父类的申明字段。*/
            Field[] fields = clazz.getDeclaredFields();

            for(int i=0;i<fields.length;i++){
                Field field = fields[i];
                Expand annotationExpand = field.getAnnotation(Expand.class);
                Pass annotationPass = field.getAnnotation(Pass.class);
                fieldName = field.getName();
                mTableTag = tableTags[0];

                if (annotationExpand == null) { // 不是Expand的
                    if (annotationPass != null) continue; // 是Pass并且不是Expand的,处理: 只作为传入参数, 则不关心
                } else {
                    if (!containExpand) { // 如果不包括扩展的,则判断过滤扩展属性
                        continue;
                    } else {
                        mTableTag = annotationExpand.value();
                        boolean isExcepted = false;
                        for (int ij=1;ij<tableTags.length;ij++) {
                            if (mTableTag.equals(tableTags[ij])) {
                                isExcepted = true;
                                break;
                            }
                        }
                        if (isExcepted) continue;
                        String name = annotationExpand.name();
                        if (!name.isEmpty()) fieldName = name;
                    }
                }
                stringBuilder.append(mTableTag)
                        .append(".")
                        .append(fieldName)
                        .append(", ");
            }
            if (containSuper) {
                clazz = clazz.getSuperclass();
            } else {
                clazz = null;
            }
        }
        return stringBuilder.deleteCharAt(stringBuilder.length()-2);
    }
}
